package com.leyuangame.core.async;

import com.leyuangame.core.BMDataContext;
import com.leyuangame.core.enums.WsServerCommand;
import com.leyuangame.core.model.Game;
import com.leyuangame.core.websocket.client.NettyClients;
import com.leyuangame.core.websocket.handler.BeiMiClient;
import com.leyuangame.core.websocket.handler.ResServer;
import com.leyuangame.dao.repository.jpa.GameRepository;
import com.leyuangame.dao.repository.jpa.PlayUserRepository;
import com.leyuangame.dao.repository.jpa.user.PlayUser;
import com.leyuangame.redis.JedisClient;
import com.leyuangame.utils.UKTools;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.tio.core.Aio;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.io.IOException;
import java.util.*;

@Component
public class MatchTask {
    @Autowired
    private JedisClient jedisClient;
    @Autowired
    private PlayUserRepository playUserRepository;
    @Autowired
    private GameRepository gameRepository;
//    @Value("${leyuancard.redis.match.perfix}")
//    private String userMatchPerfix;
//    @Value("${leyuancard.redis.gamematch.perfix}")
//    private String gameMatchPerfix;
    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private BMDataContext bmDataContext;

    @Async("processExecutor")
    public void start() throws Exception {
        while (true){
            //拿到所有游戏列表以及游戏列表下分区信息  匹配按照分区匹配
            Query query = entityManager.createNativeQuery("SELECT partionname,gamename,startnumber " +
                    "from bm_game_category a " +
                    "left join bm_game b on a.id = b.category_id " +
                    "left join bm_game_partion c on c.gameid = b.id " +
                    "WHERE  a.isopen=0 AND b.isopen=0 AND c.isopen=0");
            List list = query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
            for (Object o:list) {
                Map m = (Map) o;
                String game_name = (String) m.get("game_name");
                String partion_name = (String) m.get("partion_name");
                int start_number = (int) m.get("start_number");
                String rdsKey = bmDataContext.gameMatchPerfix+game_name+":"+partion_name;
                System.out.println(game_name+":"+partion_name+":"+start_number);
                //首先拿到游戏分类的匹配队列用户列表
                Set<String> users = jedisClient.smembers(rdsKey);
                //二次验证 避免异步 数据错误 筛选有效匹配数据
                Iterator<String> it = users.iterator();
                while (it.hasNext()) {
                    String user_id = it.next();
                    if (jedisClient.exists(bmDataContext.userMatchPerfix + user_id))
                        it.remove();
                }
                //redis set 无序  所以无需shuffle
                int step = 1;
                String room = "";
                for (String userid:users) {
                    room+=userid+"|";
                    if(step%start_number==0){//达成匹配条件 创建房间
                        String roomid = UKTools.getUUID();
                        String[] split = room.split("|");
                        try {
                            for (String userId:split) {
                                BeiMiClient client = NettyClients.getInstance().getSystemClientsMap().get("userId");
                                Aio.bindGroup(client.getChannelContext(),roomid);
                                jedisClient.del(bmDataContext.userMatchPerfix + userId);//移除匹配状态
                            }
                            jedisClient.srem(rdsKey,split);//移除所有人的匹配队列
                            //当房间内所有玩家均绑定room 成功 通知
                            //TODO
                            //Aio.sendToUser(client.getServer().getServerGroupContext(),userId,client.convertToTextResponse("123"));
                        }catch (Exception e){
                            //一旦某个人员出现错误 全部匹配失败 取消匹配队列 通知玩家重新匹配
                            for (String userId:split) {
                                BeiMiClient client = NettyClients.getInstance().getSystemClientsMap().get("userId");
                                Aio.sendToUser(client.getServer().getServerGroupContext(),userId,client.convertToTextResponse(new ResServer(WsServerCommand.MATCHFAIL.getCommand(),"匹配失败,请重新匹配")));
                            }
                        }finally {
                            room="";
                        }
                    }
                    step++;
                }
            }
            PlayUser one = playUserRepository.findOne("01eb1966041548d8bee982bc1310d6ab");
            Long testkey = jedisClient.llen("testkey");
            List<String> result = jedisClient.lrange("testkey", (long) 0, testkey);

            System.out.println(one);
            System.out.println(Thread.currentThread().getName()+"================"+result.get(0));
        }
    }
}
